package com.fengsh.nacos.exception;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * @标题
 * @作者 fengsh998
 * @创建时间 2024/2/23
 * @功能描述
 */
public class GateWeyExceptionHandler extends DefaultErrorWebExceptionHandler {

    public GateWeyExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources, ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resources, errorProperties, applicationContext);
    }

    @Override
    protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
        Map<String, Object> jsonRespBody = new HashMap<>();
        int status = 0;
        // 这里和父类的做法一样，取得DefaultErrorAttributes整理出来的所有异常信息
        Map<String, Object> error = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        // 原始的异常信息可以用getError方法取得
        Throwable throwable = getError(request);
        // 如果异常是咱们定制的异常
        if (throwable instanceof GatewayExceptionModel) {
            GatewayExceptionModel expt = (GatewayExceptionModel) throwable;
            status = expt.getStatusCode().value();
            String code = expt.getCode();
            String message = expt.getMessage();
            jsonRespBody.put("code", code);
            jsonRespBody.put("message", message);
            jsonRespBody.put("data", null);
        } else {
            status = getHttpStatus(error);
            jsonRespBody.putAll(error);
        }

        return ServerResponse
                .status(300)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(jsonRespBody));
    }
}
